#pragma once
#include <iostream>
#include <ostream>
#include <string>
#include <fstream>
#include <map>
using namespace std;
#include "nlohmann/json.hpp"
using json = nlohmann::json;

struct config {
	map<string, map<string, string>> product;
	map<string, string> self;
	map<string, map<string, string>> subduct;

	config()
	{
		ifstream conf("/etc/aliynun_config/config.json");
		json js = json::parse(conf);
		json &prod = js["production"];
		for (auto it = prod.begin(); it != prod.end(); it++) {
			string name = (*it)["productionName"];
			product[name]["productionName"] = (*it)["productionName"];
			product[name]["productionKey"] = (*it)["productionKey"];
			product[name]["productionSecret"] = (*it)["productionSecret"];
		}

		json &subdct = js["subdev_product"];
		for (auto it = subdct.begin(); it != subdct.end(); it++) {
			string name = (*it)["productionName"];
			subduct[name]["productionName"] = (*it)["productionName"];
			subduct[name]["productionKey"] = (*it)["productionKey"];
			subduct[name]["productionSecret"] = (*it)["productionSecret"];
		}

		json &sf = js["self"];
		self["AliyunHost"] = sf["AliyunHost"];
		string name = sf["ProductionName"];
		self["ProductionName"] = name;
		self["ProductionKey"] = product[name]["productionKey"];
		self["ProductionSecret"] = product[name]["productionSecret"];
		name = sf["SubProductionName"];
		self["SubProductionName"] = name;
		self["SubProductionKey"] = subduct[name]["productionKey"];
		self["SubProductionSecret"] = subduct[name]["productionSecret"];
		self["DevName"] = sf["DevName"];
		self["Devsecret"] = sf["Devsecret"];
		self["Version"] = sf["Version"];
	}

	friend ostream &operator<<(ostream &os, const config &confref)
	{
		config *conf = (config *)&confref;
		json js;
		int idx = 0;
		js["production"] = json::array();
		for (auto it = conf->product.begin(); it != conf->product.end(); it++, idx++) {
			js["production"][idx] = { { "productionName", it->first },
						  { "productionKey", it->second["productionKey"] },
						  { "productionSecret", it->second["productionSecret"] } };
		}

		js["subdev_product"] = json::array();
		idx = 0;
		for (auto it = conf->subduct.begin(); it != conf->subduct.end(); it++, idx++) {
			js["subdev_product"][idx] = { { "productionName", it->first },
						      { "productionKey", it->second["productionKey"] },
						      { "productionSecret", it->second["productionSecret"] } };
		}

		js["self"]["AliyunHost"] = conf->self["AliyunHost"];
		js["self"]["ProductionName"] = conf->self["ProductionName"];
		js["self"]["SubProductionName"] = conf->self["SubProductionName"];
		js["self"]["DevName"] = conf->self["DevName"];
		js["self"]["Devsecret"] = conf->self["Devsecret"];
		js["self"]["Version"] = conf->self["Version"];
		cout << js.dump(4) << endl;
		return os;
	}
};

extern config *g_conf;
